/*
 * complex.c
 *
 *  Created on: 14/03/2011
 *      Author: Yotam and Gilad
 */
#include <stdlib.h>
#include <math.h>
#include "mtm_ex1.h"
#include "complex.h"

enum {
	ZERO = 0, MINUS = -1
};

Complex complexCreate(double real, double imaginary) {
	Complex newComplex;
	newComplex.real = real;
	newComplex.imaginary = imaginary;
	return newComplex;
}

Complex complexCreateInvalid() {
	Complex invalidComplex;
	invalidComplex.real = NAN;
	invalidComplex.imaginary = NAN;
	return invalidComplex;
}

Complex complexCreateFromPolar(double absoluteValue, double argument) {
	Complex newComplex;
	newComplex.real = absoluteValue * cos(argument);
	newComplex.imaginary = absoluteValue * sin(argument);
	return newComplex;
}

bool complexIsValid(Complex complex) {
	if ((isfinite(complex.real)) && (complex.real != NAN)
			&& (isfinite(complex.imaginary)) && (complex.imaginary != NAN)) {
		return true;
	}
	return false;
}

bool complexIsZero(Complex complex) {
	if ((isDoubleEqual(complex.real, ZERO)) && (isDoubleEqual(
			complex.imaginary, ZERO))) {
		return true;
	}
	return false;
}

bool complexIsEqual(Complex complex1, Complex complex2) {
	if ((isDoubleEqual(complex1.real, complex2.real)) && (isDoubleEqual(
			complex1.imaginary, complex2.imaginary))) {
		return true;
	}
	return false;
}

Complex complexNegate(Complex complex) {
	complex.real = (MINUS) * complex.real;
	complex.imaginary = (MINUS) * complex.imaginary;
	return complex;
}

Complex complexAdd(Complex complex1, Complex complex2) {
	Complex complexSum;
	complexSum.real = complex1.real + complex2.real;
	complexSum.imaginary = complex1.imaginary + complex2.imaginary;
	return complexSum;
}

Complex complexSubtract(Complex complex1, Complex complex2) {
	Complex newComplex;
	newComplex.real = complex1.real - complex2.real;
	newComplex.imaginary = complex1.imaginary - complex2.imaginary;
	return newComplex;
}

Complex complexMultiply(Complex complex1, Complex complex2) {
	double real1 = complex1.real, real2 = complex2.real, imaginary1 =
			complex1.imaginary, imaginary2 = complex2.imaginary;
	Complex multipliedComplex;
	multipliedComplex.real = real1 * real2 - imaginary1 * imaginary2;
	multipliedComplex.imaginary = real1 * imaginary2 + imaginary1 * real2;
	return multipliedComplex;
}

Complex complexConjugate(Complex complex) {
	complex.imaginary = (MINUS) * complex.imaginary;
	return complex;
}

double complexAbsoluteValue(Complex complex) {
	return sqrt((complex.real) * (complex.real) + (complex.imaginary)
			* (complex.imaginary));
}

double complexArgument(Complex complex) {
	return atan2(complex.imaginary, complex.real);
}

Complex complexInverse(Complex complex) {
	Complex inverse = complexConjugate(complex);
	inverse.real /= (pow(complexAbsoluteValue(complex), 2));
	inverse.imaginary /= (pow(complexAbsoluteValue(complex), 2));
	return inverse;
}

Complex complexDivide(Complex complex1, Complex complex2) {
	Complex inverse = complexInverse(complex2);
	return (complexMultiply(complex1, inverse));
}

